package com.erp.framework.util;

import java.math.BigDecimal;
import java.security.InvalidParameterException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;

import com.erp.framework.SimpleConstants;
import com.erp.framework.model.dao.ServiceLocator;
import com.erp.framework.util.logger.Logger;

public class DateTimeUtil implements SimpleConstants {

	public static Date addDay(Date date, int nDays) {
		GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(TIMEZONE));
		cal.setTime(date);

		cal.add(Calendar.DATE, nDays);

		return cal.getTime();
	}

	public static Date addWeek(Date date, int nWeeks) {
		GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(TIMEZONE));
		cal.setTime(date);

		cal.add(Calendar.WEEK_OF_YEAR, nWeeks);

		return cal.getTime();
	}

	public static Date addMonth(Date date, int nMonths) {
		GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(TIMEZONE));
		cal.setTime(date);

		cal.add(Calendar.MONTH, nMonths);

		return cal.getTime();
	}

	public static Date addYear(Date date, int nYears) {
		GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(TIMEZONE));
		cal.setTime(date);

		cal.add(Calendar.YEAR, nYears);

		return cal.getTime();
	}
	
	
	////////////////////////functions below this line need to be mofidied, VICTOR ///////////////
	
	
	// public static String formatDate(Date date) {
	// SimpleDateFormat sfmt = new SimpleDateFormat(DATE_ONLY_FORMAT, Locale.TRADITIONAL_CHINESE);
	// return sfmt.format(date);
	// }
	//
	// public static String formatDate(String dateStr) {
	// SimpleDateFormat sfmt = new SimpleDateFormat(DATE_ONLY_FORMAT, Locale.TRADITIONAL_CHINESE);
	// Date date = null;
	// try {
	// date = sfmt.parse(dateStr);
	// return sfmt.format(date);
	// } catch (Exception e) {
	// return "";
	// }
	// }

	/** Get current time from as long, default timezone */
	public static long now() {
		GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(TIMEZONE));
		// return
		// cal.getTimeInMillis()+InitialSystemParameters.currDateOffset*1000; //
		// java version 1.4
		return cal.getTime().getTime() + 1000;
		// 1.3
	}

	/** Get current time as long, specific timezone */
	public static long now(String timezone) {
		GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(timezone));
		// return
		// cal.getTimeInMillis()+InitialSystemParameters.currDateOffset*1000; //
		// java version 1.4
		return cal.getTime().getTime() + 1000;
		// 1.3
	}

	/** Get current time as Timestamp, default timezone */
	public static Timestamp getDateTime() {
		return new Timestamp(now());
	}

	/** Get current time as Timestamp, specific timezone */
	public static Timestamp getDateTime(String timezone) {
		return new Timestamp(now(timezone));
	}

	/** Get current time as GregorianCalendar, specific timezone */
	public static GregorianCalendar getCalendar(String timezone) {
		GregorianCalendar gcal = new GregorianCalendar(TimeZone.getTimeZone(timezone));
		gcal.setTime(getDateTime(timezone));
		return gcal;
	}

	/** Get current time as GregorianCalendar, default timezone */
	public static GregorianCalendar getCalendar() {
		GregorianCalendar gcal = new GregorianCalendar();
		gcal.setTime(getDateTime());
		return gcal;
	}

	/** Get current time as date time string, default timezone */
	public static String getDateTimeString(String format) {
		SimpleDateFormat formatter = new SimpleDateFormat(format);
		String strDate = formatter.format(new Date(getDateTime().getTime()));
		return strDate;
	}

	/*
	 * Date/Time manipulation operations based on input date or time fields
	 */

	public static String getDateTimeString(Timestamp time, String format) {
		SimpleDateFormat formatter = new SimpleDateFormat(format);
		String strDate = formatter.format(new Date(time.getTime()));
		return strDate;
	}

	public static String getDateTimeString(Date time, String format) {
		SimpleDateFormat formatter = new SimpleDateFormat(format);
		String strDate = formatter.format(time);
		return strDate;
	}

	public static Timestamp getDate(String strYear, String strMonth, String strDay) {
		GregorianCalendar cal = new GregorianCalendar(Integer.parseInt(strYear), Integer.parseInt(strMonth) - 1, Integer
				.parseInt(strDay));
		return new Timestamp(cal.getTime().getTime());
	}

	public static Date getDate2(String strYear, String strMonth, String strDay) {
		return getDate2(Integer.parseInt(strYear), Integer.parseInt(strMonth), Integer.parseInt(strDay));
	}

	public static Date getDate2(int strYear, int strMonth, int strDay) {
		GregorianCalendar cal = new GregorianCalendar(strYear, strMonth - 1, strDay);
		return cal.getTime();
	}

	public static boolean isValidDate(String strYear, String strMonth, String strDay) {
		int day = 0;
		int month = 0;
		int year = 0;

		try {
			day = Integer.parseInt(strDay);
			month = Integer.parseInt(strMonth);
			year = Integer.parseInt(strYear);
		} catch (Exception e) {
			return false;
		}

		if ((month < 1) || (month > 12)) {
			return false;
		}

		if ((year < 1800) || (year > 9999)) {
			return false;
		}

		if ((day < 1) || (day > getDaysInMonth(year, month))) {
			return false;
		}

		return true;

	}

	public static boolean isValidTime(String strHour, String strMinute, String strSecond) {
		int hour = 0;
		int minute = 0;
		int second = 0;

		try {
			hour = Integer.parseInt(strHour);
			minute = Integer.parseInt(strMinute);
			second = Integer.parseInt(strSecond);
		} catch (Exception e) {
			return false;
		}

		if ((hour < 0) || (hour > 23)) {
			return false;
		}

		if ((minute < 0) || (minute > 59)) {
			return false;
		}

		if ((second < 0) || (second > 59)) {
			return false;
		}

		return true;
	}

	// Get total number of days in a month
	public static int getDaysInMonth(int year, int month) {
		int days = 0;

		if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
			days = 31;
		} else if (month == 4 || month == 6 || month == 9 || month == 11) {
			days = 30;
		} else if (month == 2) {
			if (isLeapYear(year)) {
				days = 29;
			} else {
				days = 28;
			}
		}
		return days;
	}

	// CHECK TO SEE IF YEAR IS A LEAP YEAR
	public static boolean isLeapYear(int year) {
		if (((year % 4) == 0) && ((year % 100) != 0) || ((year % 400) == 0)) {
			return true;
		} else {
			return false;
		}
	}

	public static Date cloneDate(Date date) {
		GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(TIMEZONE));
		cal.setTime(date);

		return cal.getTime();
	}

	/**
	 * Returns true if the date, month and year of the two dates are equal
	 */
	public static boolean equalsDateMonthYear(Date date1, Date date2) {
		int d1, d2, m1, m2, y1, y2;

		GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(TIMEZONE));
		cal.setTime(date1);
		d1 = cal.get(Calendar.DAY_OF_MONTH);
		m1 = cal.get(Calendar.MONTH);
		y1 = cal.get(Calendar.YEAR);

		cal.setTime(date2);
		d2 = cal.get(Calendar.DAY_OF_MONTH);
		m2 = cal.get(Calendar.MONTH);
		y2 = cal.get(Calendar.YEAR);

		return ((d1 == d2) && (m1 == m2) && (y1 == y2)) ? true : false;

	}

	public static boolean greaterOrEqualDateMonthYear(Date date1, Date date2) {
		int d1, d2, m1, m2, y1, y2;

		GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(TIMEZONE));
		cal.setTime(date1);
		d1 = cal.get(Calendar.DAY_OF_MONTH);
		m1 = cal.get(Calendar.MONTH);
		y1 = cal.get(Calendar.YEAR);

		cal.setTime(date2);
		d2 = cal.get(Calendar.DAY_OF_MONTH);
		m2 = cal.get(Calendar.MONTH);
		y2 = cal.get(Calendar.YEAR);

		return ((d1 >= d2) && (m1 >= m2) && (y1 >= y2)) ? true : false;

	}

	public static boolean greaterDateMonthYear(Date date1, Date date2) {
		int d1, d2, m1, m2, y1, y2;

		GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(TIMEZONE));
		cal.setTime(date1);
		d1 = cal.get(Calendar.DAY_OF_MONTH);
		m1 = cal.get(Calendar.MONTH);
		y1 = cal.get(Calendar.YEAR);

		cal.setTime(date2);
		d2 = cal.get(Calendar.DAY_OF_MONTH);
		m2 = cal.get(Calendar.MONTH);
		y2 = cal.get(Calendar.YEAR);

		return ((d1 > d2) && (m1 > m2) && (y1 > y2)) ? true : false;

	}

	public static boolean lessOrEqualDateMonthYear(Date date1, Date date2) {
		int d1, d2, m1, m2, y1, y2;

		GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(TIMEZONE));
		cal.setTime(date1);
		d1 = cal.get(Calendar.DAY_OF_MONTH);
		m1 = cal.get(Calendar.MONTH);
		y1 = cal.get(Calendar.YEAR);

		cal.setTime(date2);
		d2 = cal.get(Calendar.DAY_OF_MONTH);
		m2 = cal.get(Calendar.MONTH);
		y2 = cal.get(Calendar.YEAR);

		return ((d1 <= d2) && (m1 <= m2) && (y1 <= y2)) ? true : false;

	}

	public static boolean lessDateMonthYear(Date date1, Date date2) {
		int d1, d2, m1, m2, y1, y2;

		GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(TIMEZONE));
		cal.setTime(date1);
		d1 = cal.get(Calendar.DAY_OF_MONTH);
		m1 = cal.get(Calendar.MONTH);
		y1 = cal.get(Calendar.YEAR);

		cal.setTime(date2);
		d2 = cal.get(Calendar.DAY_OF_MONTH);
		m2 = cal.get(Calendar.MONTH);
		y2 = cal.get(Calendar.YEAR);

		return ((d1 < d2) && (m1 < m2) && (y1 < y2)) ? true : false;

	}

	

	public static Date rolledByDays(Date date, int nDays) {
		GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(TIMEZONE));
		cal.setTime(date);
		cal.roll(Calendar.DATE, nDays);

		return cal.getTime();
	}

	public static boolean isSunday(Date date) {
		GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone(TIMEZONE));
		cal.setTime(date);
		if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY)
			return true;
		else
			return false;
	}

	/**
	 * If TRUE, t1 is the after date of t2. Only the Yesr, Month and Day are compared.
	 * 
	 * Method Name : isAfterDate()
	 * 
	 * @param t1
	 * @param t2
	 * @return
	 */
	public static boolean isAfterDate(Timestamp t1, Timestamp t2) {
		Timestamp tempT1 = null;
		Timestamp tempT2 = null;

		if (t1 != null && t2 != null) {
			tempT1 = (Timestamp) t1.clone();
			tempT2 = (Timestamp) t2.clone();

			tempT1 = resetTime(tempT1);
			tempT2 = resetTime(tempT2);

			return tempT1.after(tempT2);
		} else {
			return false;
		}
	}

	/**
	 * If TRUE, t1 is the before date of t2. Only the Yesr, Month and Day are compared.
	 * 
	 * Method Name : isBeforeDate()
	 * 
	 * @param t1
	 * @param t2
	 * @return
	 */
	public static boolean isBeforeDate(Timestamp t1, Timestamp t2) {
		Timestamp tempT1 = null;
		Timestamp tempT2 = null;

		if (t1 != null && t2 != null) {
			tempT1 = (Timestamp) t1.clone();
			tempT2 = (Timestamp) t2.clone();

			tempT1 = resetTime(tempT1);
			tempT2 = resetTime(tempT2);

			return tempT1.before(tempT2);
		} else {
			return false;
		}
	}

	/**
	 * Method Name : resetTime()
	 * 
	 * @param _timestamp
	 * @return
	 */
	private static Timestamp resetTime(Timestamp _timestamp) {
		Calendar calendar = null;

		if (_timestamp != null) {
			calendar = getCalendar();

			calendar.setTime(_timestamp);
			calendar.set(Calendar.SECOND, 0);
			calendar.set(Calendar.MINUTE, 0);
			calendar.set(Calendar.HOUR, 0);
			calendar.set(Calendar.AM_PM, Calendar.AM);

		}

		return new Timestamp(calendar.getTime().getTime());
	}

	/**
	 * Append the current time to the passed in Date.
	 * 
	 * Method Name : addCurrentTimeTo()
	 * 
	 * @param myDate
	 * @return
	 */
	public static Timestamp addCurrentTimeTo(Timestamp myDate) {
		Calendar cal = null;

		cal = getCalendar();
		cal.set(Calendar.YEAR, Integer.parseInt(DateTimeUtil.getDateTimeString(myDate, YEAR_FORMAT)));
		cal.set(Calendar.MONTH, Integer.parseInt(DateTimeUtil.getDateTimeString(myDate, MTH_FORMAT)) - 1);
		cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(DateTimeUtil.getDateTimeString(myDate, DAY_FORMAT)));

		return new Timestamp(cal.getTime().getTime());
	}

	/**
	 * check if the input date's last date - hoursBefore *** FOR DELIVERY REQUEST ***
	 * 
	 * @param deliveryDate,
	 *            hoursBefore
	 */
	public static boolean isUrgentDeliveryDate(String deliveryDate, int hoursBefore) throws Exception {
		Date currentDate = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat(CommonUtil.INPUT_DATETIME_FORMAT);
		GregorianCalendar gc = new GregorianCalendar();
		Date delivDate;
		boolean rslt = false;
		try {
			delivDate = sdf.parse(deliveryDate);
			gc.setTime(delivDate);
			// gc.add(java.util.Calendar.DAY_OF_YEAR, -1);
			gc.add(java.util.Calendar.HOUR, -(hoursBefore));
			rslt = currentDate.after(gc.getTime()) && currentDate.before(delivDate);
		} catch (Exception e) {
			rslt = false;
			throw new Exception("Error occured when parsing the delivery date: " + e.toString());

		}
		return rslt;
	}

	public static int compareDate(String op1, String op2, String formatMask) throws InvalidParameterException, ParseException {
		java.util.Date date1 = null;
		java.util.Date date2 = null;

		// date1 = SimpleString.stringWithSlashToDate(op1);
		// date2 = stringWithSlashToDate(op2);

		if (date1 == null)
			date1 = ConvertUtil.stringToDate(op1, formatMask, SimpleConstants.DEFAULT_LOCALE);

		if (date2 == null)
			date2 = ConvertUtil.stringToDate(op2, formatMask, SimpleConstants.DEFAULT_LOCALE);

		if (date1 == null || date2 == null)
			throw new InvalidParameterException();

		return date1.compareTo(date2);
	}

	/**
	 * @param date
	 * @param hours
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static java.util.Date addHours(java.util.Date date, int hours, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		gcal.add(Calendar.HOUR, hours);
		return gcal.getTime();
	}

	/**
	 * @param date
	 * @param days
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static java.util.Date addDays(java.util.Date date, int days, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		gcal.add(Calendar.DAY_OF_YEAR, days);
		return gcal.getTime();
	}

	/**
	 * @param date
	 * @param milliSeconds
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static java.util.Date addMilliSeconds(java.util.Date date, int milliSeconds, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		gcal.add(Calendar.MILLISECOND, milliSeconds);
		return gcal.getTime();
	}

	/**
	 * @param date
	 * @param minutes
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static java.util.Date addMinutes(java.util.Date date, int minutes, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		gcal.add(Calendar.MINUTE, minutes);
		return gcal.getTime();
	}

	/**
	 * @param date
	 * @param months
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static java.util.Date addMonths(java.util.Date date, int months, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		gcal.add(Calendar.MONTH, months);
		return gcal.getTime();
	}

	/**
	 * @param date
	 * @param seconds
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static java.util.Date addSeconds(java.util.Date date, int seconds, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		gcal.add(Calendar.SECOND, seconds);
		return gcal.getTime();
	}

	/**
	 * @param date
	 * @param weeks
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static java.util.Date addWeeks(java.util.Date date, int weeks, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		gcal.add(Calendar.WEEK_OF_YEAR, weeks);
		return gcal.getTime();
	}

	/**
	 * @param date
	 * @param years
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static java.util.Date addYears(java.util.Date date, int years, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		gcal.add(Calendar.YEAR, years);
		return gcal.getTime();
	}

	/**
	 * @param date
	 * @param field
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getActualMaximum(java.util.Date date, int field, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return (gcal.getActualMaximum(field));
	}

	/**
	 * @param date
	 * @param field
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getActualMinimum(java.util.Date date, int field, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return (gcal.getActualMinimum(field));
	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return AM if the given date is before noon; PM otherise.
	 */
	public static int getAmPm(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return gcal.get(Calendar.AM_PM);
	}

	/**
	 * @param year
	 * @param month
	 * @param day
	 * @return
	 */
	public static java.util.Date getDate(int year, int month, int day) {
		GregorianCalendar cal = new GregorianCalendar(year, month - 1, day);
		return cal.getTime();
	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getDayOfMonth(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return gcal.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getDayOfWeek(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return gcal.get(Calendar.DAY_OF_WEEK);
	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getDayOfWeekInMonth(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return gcal.get(Calendar.DAY_OF_WEEK_IN_MONTH);
	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getDayOfYear(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return gcal.get(Calendar.DAY_OF_YEAR);
	}

	/**
	 * @param date
	 * @param field
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getGreatestMinimum(java.util.Date date, int field, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return (gcal.getGreatestMinimum(field));
	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getHour(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return gcal.get(Calendar.HOUR);
	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getHourOfDay(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return gcal.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * @param date
	 * @param field
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getLeastMaximum(java.util.Date date, int field, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return (gcal.getLeastMaximum(field));
	}

	/**
	 * @param date
	 * @param field
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getMaximum(java.util.Date date, int field, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return (gcal.getMaximum(field));
	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getMilliSecond(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return gcal.get(Calendar.MILLISECOND);
	}

	/**
	 * @param date
	 * @param field
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getMinimum(java.util.Date date, int field, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return (gcal.getMinimum(field));
	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getMinute(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return gcal.get(Calendar.MINUTE);
	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getMonth(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return (gcal.get(Calendar.MONTH) + 1);
	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getSecond(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return gcal.get(Calendar.SECOND);
	}

	/**
	 * @param strYear
	 * @param strMonth
	 * @param strDay
	 * @return
	 */
	public static Timestamp getTimestamp(String strYear, String strMonth, String strDay) {
		GregorianCalendar cal = new GregorianCalendar(Integer.parseInt(strYear), Integer.parseInt(strMonth) - 1, Integer
				.parseInt(strDay));
		return new Timestamp(cal.getTime().getTime());
	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getWeekOfMonth(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return gcal.get(Calendar.WEEK_OF_MONTH);
	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getWeekOfYear(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return gcal.get(Calendar.WEEK_OF_YEAR);
	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static int getYear(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return gcal.get(Calendar.YEAR);
	}

	/**
	 * @param date1
	 * @param date2
	 * @return true if day, month and year are the same; false otherwise.
	 */
	public static boolean isDateMonthYearEqual(java.util.Date date1, java.util.Date date2) {
		int d1, d2, m1, m2, y1, y2;

		GregorianCalendar cal = new GregorianCalendar(SimpleConstants.DEFAULT_TIMEZONE);
		cal.setTime(date1);
		d1 = cal.get(Calendar.DAY_OF_MONTH);
		m1 = cal.get(Calendar.MONTH);
		y1 = cal.get(Calendar.YEAR);

		cal.setTime(date2);
		d2 = cal.get(Calendar.DAY_OF_MONTH);
		m2 = cal.get(Calendar.MONTH);
		y2 = cal.get(Calendar.YEAR);

		return ((d1 == d2) && (m1 == m2) && (y1 == y2)) ? true : false;
	}

	/**
	 * @param date1
	 * @param date2
	 * @return true if day, month and year of date1 > those of date2; false otherwise.
	 */
	public static boolean isDateMonthYearGreater(java.util.Date date1, java.util.Date date2) {
		int d1, d2, m1, m2, y1, y2;

		GregorianCalendar cal = new GregorianCalendar(SimpleConstants.DEFAULT_TIMEZONE);
		cal.setTime(date1);
		d1 = cal.get(Calendar.DAY_OF_MONTH);
		m1 = cal.get(Calendar.MONTH);
		y1 = cal.get(Calendar.YEAR);

		cal.setTime(date2);
		d2 = cal.get(Calendar.DAY_OF_MONTH);
		m2 = cal.get(Calendar.MONTH);
		y2 = cal.get(Calendar.YEAR);

		return ((d1 > d2) && (m1 > m2) && (y1 > y2)) ? true : false;

	}

	/**
	 * @param date1
	 * @param date2
	 * @return true if day, month and year of date1 >= those of date2; false otherwise.
	 */
	public static boolean isDateMonthYearGreaterOrEqual(java.util.Date date1, java.util.Date date2) {
		int d1, d2, m1, m2, y1, y2;

		GregorianCalendar cal = new GregorianCalendar(SimpleConstants.DEFAULT_TIMEZONE);
		cal.setTime(date1);
		d1 = cal.get(Calendar.DAY_OF_MONTH);
		m1 = cal.get(Calendar.MONTH);
		y1 = cal.get(Calendar.YEAR);

		cal.setTime(date2);
		d2 = cal.get(Calendar.DAY_OF_MONTH);
		m2 = cal.get(Calendar.MONTH);
		y2 = cal.get(Calendar.YEAR);

		return ((d1 >= d2) && (m1 >= m2) && (y1 >= y2)) ? true : false;

	}

	/**
	 * @param date1
	 * @param date2
	 * @return true if day, month and year of date1 < those of date2; false otherwise.
	 */
	public static boolean isDateMonthYearLess(java.util.Date date1, java.util.Date date2) {
		int d1, d2, m1, m2, y1, y2;

		GregorianCalendar cal = new GregorianCalendar(SimpleConstants.DEFAULT_TIMEZONE);
		cal.setTime(date1);
		d1 = cal.get(Calendar.DAY_OF_MONTH);
		m1 = cal.get(Calendar.MONTH);
		y1 = cal.get(Calendar.YEAR);

		cal.setTime(date2);
		d2 = cal.get(Calendar.DAY_OF_MONTH);
		m2 = cal.get(Calendar.MONTH);
		y2 = cal.get(Calendar.YEAR);

		return ((d1 < d2) && (m1 < m2) && (y1 < y2)) ? true : false;

	}

	/**
	 * @param date1
	 * @param date2
	 * @return true if day, month and year of date1 <= those of date2; false otherwise.
	 */
	public static boolean isDateMonthYearLessOrEqual(java.util.Date date1, java.util.Date date2) {
		int d1, d2, m1, m2, y1, y2;

		GregorianCalendar cal = new GregorianCalendar(SimpleConstants.DEFAULT_TIMEZONE);
		cal.setTime(date1);
		d1 = cal.get(Calendar.DAY_OF_MONTH);
		m1 = cal.get(Calendar.MONTH);
		y1 = cal.get(Calendar.YEAR);

		cal.setTime(date2);
		d2 = cal.get(Calendar.DAY_OF_MONTH);
		m2 = cal.get(Calendar.MONTH);
		y2 = cal.get(Calendar.YEAR);

		return ((d1 <= d2) && (m1 <= m2) && (y1 <= y2)) ? true : false;

	}

	/**
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static boolean isLeapYear(java.util.Date date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.setTime(date);
		return gcal.isLeapYear(gcal.get(Calendar.YEAR));
	}

	/**
	 * @param dateVal
	 * @param formatMask
	 * @param locale
	 * @return
	 */
	public static boolean isValidDate(String dateVal, String formatMask, Locale locale) {
		if (CommonUtil.isEmpty(dateVal) || CommonUtil.isEmpty(formatMask)
				|| dateVal.trim().length() != formatMask.trim().length())
			return false;

		SimpleDateFormat formatter = new SimpleDateFormat(formatMask, locale);
		formatter.setLenient(false);
		ParsePosition pos = new ParsePosition(0);
		java.util.Date d = formatter.parse(dateVal.trim(), pos);
		return (pos.getErrorIndex() == -1 && pos.getIndex() == dateVal.length());
	}

	public static boolean isValidDateTime(String dateTimeStr, String formatMask, Locale locale) {
		if ((dateTimeStr == null) || (dateTimeStr.trim().equals("")))
			return false;

		if ((formatMask == null) || (formatMask.trim().equals("")))
			return false;

		if (dateTimeStr.trim().length() != formatMask.trim().length())
			return false;

		SimpleDateFormat sdf = new SimpleDateFormat(formatMask, locale);
		java.util.Date date = null;
		try {
			date = sdf.parse(dateTimeStr.trim());
			return isValidDate(dateTimeStr, formatMask, locale);
		} catch (Exception e) {
			sdf = null;
			return false;
		}
	}

	/**
	 * @param day
	 * @return true if day <=31 and day >=1
	 */
	public static boolean isValidDay(int day) {
		return ((day <= SimpleConstants.MAX_DAY) && (day >= SimpleConstants.MIN_DAY));
	}

	/**
	 * @param day
	 * @return true if day <=31 and day >=1
	 */
	public static boolean isValidDay(String day) {
		if ((day == null) || (day.trim().equals("")))
			return false;
		return isValidDay(Integer.parseInt(day.trim()));
	}

	/**
	 * @param hour
	 * @return true if hour <=23 and day >=0
	 */
	public static boolean isValidHour(int hour) {
		return ((hour <= SimpleConstants.MAX_HOUR) && (hour >= SimpleConstants.MIN_HOUR));
	}

	/**
	 * @param hour
	 * @return true if hour <=23 and day >=0
	 */
	public static boolean isValidHour(String hour) {
		if ((hour == null) || (hour.trim().equals("")))
			return false;
		return isValidHour(Integer.parseInt(hour.trim()));
	}

	/**
	 * @param milliSecond
	 * @return true if milliSecond <=999 and milliSecond >=0
	 */
	public static boolean isValidMilliSecond(int milliSecond) {
		return ((milliSecond <= SimpleConstants.MAX_MILLISECOND) && (milliSecond >= SimpleConstants.MIN_MILLISECOND));
	}

	/**
	 * @param milliSecond
	 * @return true if milliSecond <=999 and milliSecond >=0
	 */
	public static boolean isValidMilliSecond(String milliSecond) {
		if ((milliSecond == null) || (milliSecond.trim().equals("")))
			return false;
		return isValidMilliSecond(Integer.parseInt(milliSecond.trim()));
	}

	/**
	 * @param minute
	 * @return true if minute <=59 and minute >=0
	 */
	public static boolean isValidMinute(int minute) {
		return ((minute <= SimpleConstants.MAX_MINUTE) && (minute >= SimpleConstants.MIN_MINUTE));
	}

	/**
	 * @param minute
	 * @return true if minute <=59 and minute >=0
	 */
	public static boolean isValidMinute(String minute) {
		if ((minute == null) || (minute.trim().equals("")))
			return false;
		return isValidMinute(Integer.parseInt(minute.trim()));
	}

	/**
	 * @param month
	 * @return
	 */
	public static boolean isValidMonth(int month) {
		return ((month <= SimpleConstants.MAX_MONTH) && (month >= SimpleConstants.MIN_MONTH));
	}

	/**
	 * @param month
	 * @return
	 */
	public static boolean isValidMonth(String month) {
		if ((month == null) || (month.trim().equals("")))
			return false;
		return isValidMonth(Integer.parseInt(month.trim()));
	}

	/**
	 * @param second
	 * @return true if second <=59 and second >=0
	 */
	public static boolean isValidSecond(int second) {
		return ((second <= SimpleConstants.MAX_SECOND) && (second >= SimpleConstants.MIN_SECOND));
	}

	/**
	 * @param second
	 * @return true if second <=59 and second >=0
	 */
	public static boolean isValidSecond(String second) {
		if ((second == null) || (second.trim().equals("")))
			return false;
		return isValidSecond(Integer.parseInt(second.trim()));
	}

	/**
	 * @param year
	 * @return true if year <=2099 and year >= 1970
	 */
	public static boolean isValidYear(int year) {
		return ((year <= SimpleConstants.MAX_YEAR) && (year >= SimpleConstants.MIN_YEAR));
	}

	/**
	 * @param year
	 * @return true if year <=2099 and year >= 1970
	 */
	public static boolean isValidYear(String year) {
		if ((year == null) || (year.trim().equals("")))
			return false;
		return isValidYear(Integer.parseInt(year.trim()));
	}

	/**
	 * @param year
	 * @param month
	 * @param date
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static java.util.Date getDate(int year, int month, int date, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.set(year, month - 1, date);
		return gcal.getTime();
	}

	/**
	 * @param year
	 * @param month
	 * @param date
	 * @param hour
	 * @param minute
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static java.util.Date getDate(int year, int month, int date, int hour, int minute, TimeZone timezone, Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.set(year, month - 1, date, hour, minute);
		return gcal.getTime();
	}

	/**
	 * @param year
	 * @param month
	 * @param date
	 * @param hour
	 * @param minute
	 * @param second
	 * @param timezone
	 * @param locale
	 * @return
	 */
	public static java.util.Date getDate(int year, int month, int date, int hour, int minute, int second, TimeZone timezone,
			Locale locale) {
		GregorianCalendar gcal = new GregorianCalendar(timezone, locale);
		gcal.set(year, month - 1, date, hour, minute, second);
		return gcal.getTime();
	}

	public static java.sql.Timestamp getDBSysDate() throws Exception {
		Connection conn = null;
		Timestamp sysDate = null;

		try {
			conn = ServiceLocator.getInstance().getDSDBConnection();
			sysDate = getDBSysDate(conn);
		} catch (Exception e) {
			Logger.debug("in getDBSysDate error : " + e.getMessage());
			throw e;
		} finally {
			try {
				if (conn != null)
					conn.close();
			} catch (Exception e) {
				Logger.debug("in getDBSysDate close conn error : " + e.getMessage());
			}
		}

		return sysDate;
	}

	public static Timestamp getDBSysDate(Connection conn) throws Exception {
		DatabaseMetaData dbmd = conn.getMetaData();
		String dbName = dbmd.getDatabaseProductName().toUpperCase();
		String query = "SELECT SYSDATE FROM DUAL";
		PreparedStatement pStmt = null;
		ResultSet rs = null;
		Timestamp sysDate = null;

		Logger.debug("in getDBSysDate dbName = " + dbName);

		if (dbName.indexOf("ORACLE") >= 0) {
			// oracle
			query = "SELECT SYSDATE FROM DUAL";
		} else if (dbName.indexOf("MICROSOFT SQL SERVER") >= 0) {
			// sql server
			query = "SELECT GETDATE()";
		} else if (dbName.indexOf("INFORMIX") >= 0) {
			// informix
			query = "SELECT CURRENT FROM DUAL";
		} else if (dbName.indexOf("ADAPTIVE SERVER") >= 0 || dbName.indexOf("SYBASE") >= 0) {
			// sybase
			query = "SELECT GETDATE()";
		} else {
			// default oracle
		}

		try {
			pStmt = conn.prepareStatement(query);
			rs = pStmt.executeQuery();
			if (rs != null) {
				if (rs.next()) {
					sysDate = rs.getTimestamp(1);
				}
			}
		} catch (Exception e) {
			Logger.debug("in getDBSysDate error in get sysdate: " + e.getMessage());
			throw e;
		} finally {
			try {
				if (rs != null)
					rs.close();
			} catch (Exception e) {
				Logger.debug("in getDBSysDate error in closing rs: " + e.getMessage());
			}
			try {
				if (pStmt != null)
					pStmt.close();
			} catch (Exception e) {
				Logger.debug("in getDBSysDate error in closing pStmt: " + e.getMessage());
			}
		}

		return sysDate;
	}

	public static Date minusDays(Date src, BigDecimal days) {
		if (src == null || days == null)
			return null;

		return addDays(src, days.intValue() * -1);
	}

	public static Date minusDays(Date src, int days) {
		if (src == null)
			return null;

		return addDays(src, days * -1);
	}

	public static Date minusDays(String src, int days) {
		if (src == null)
			return null;

		return addDays(src, days * -1);
	}

	public static Date addDays(String src, int days) {
		Date date;
		if (src == null)
			return null;

		// date = stringWithSlashToDate(src);
		date = CommonUtil.stringToDate(src);

		if (date == null)
			date = CommonUtil.stringToDate(src);

		return addDays(date, days);
	}

	public static Date addDays(Date src, BigDecimal days) {
		if (src == null || days == null)
			return null;

		return addDays(src, days.intValue());
	}

	public static Date addDays(Date src, int days) {
		if (src == null)
			return null;

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(src);
		calendar.add(Calendar.DATE, days);

		return calendar.getTime();
	}

	public static int compareDate(String op1, String op2) throws InvalidParameterException {
		Date date1 = null;
		Date date2 = null;

		// date1 = stringWithSlashToDate(op1);
		// date2 = stringWithSlashToDate(op2);
		date1 = CommonUtil.stringToDate(op1);
		date2 = CommonUtil.stringToDate(op2);

		if (date1 == null)
			date1 = CommonUtil.stringToDate(op1);

		if (date2 == null)
			date2 = CommonUtil.stringToDate(op2);

		if (date1 == null || date2 == null)
			throw new InvalidParameterException();

		return date1.compareTo(date2);
	}

	public static int compareCurrenDate(String op1) throws InvalidParameterException {
		Date date2 = new Date();
		String op2 = CommonUtil.dateToString(date2);
		
		return compareDate(op1, op2);
	}

//	public static int compareDate(String op1, String op2, String formatMask) throws InvalidParameterException, ParseException {
//		return DateTimeUtil.compareDate(op1, op2, formatMask);
//	}
}
